<?php
/*
 * @Description    : HTTP异常挂起类
 * @Version        : 1.0.0
 * @Author         : QianLong
 * @Date           : 2019-11-21 10:20:58
 * @LastEditors    : QianLong
 * @LastEditTime   : 2023-03-23 10:42:14
 */

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://doc.hyperf.io
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
 */

namespace App\Exception\Handler;

use App\Exception\ApiException;
use App\Exception\NullReturnException;
use App\Service\Common;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use Hyperf\HttpServer\Contract\RequestInterface;

class HttpExceptionHandler extends ExceptionHandler
{
    /**
     * @var RequestInterface
     */
    protected $request;

    public function __construct(RequestInterface $request)
    {
        $this->request = $request;
    }

    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        if ($throwable instanceof ApiException) {
            $data = json_encode([
                'code' => ($throwable->getCode()) ? $throwable->getCode() : 999,
                'data' => array(),
                'msg' => ($throwable->getMessage()) ? $throwable->getMessage() : '未知异常'
            ], 272);
            $code = 200;
        } elseif ($throwable instanceof NullReturnException) {
            return false;
        } else {
            // 格式化输出
            $requestId = createId('RE');
            $logData['time'] = date('Y-m-d H:i:s');
            $logData['request_id'] = $requestId;
            $logData['url'] = $this->request->fullUrl();
            $logData['file'] = $throwable->getFile() . ' ; Line: ' . $throwable->getLine();
            $logData['message'] = $throwable->getMessage();
            $logData['trace'] = $throwable->getTraceAsString();
            $logData['client_ip'] = getClientIp($this->request);
            (new Common())->logPush($logData);
            // unset($logData, $requestId);
            $code = 500;
            $data = json_encode([
                'code' => ($throwable->getCode()) ? $throwable->getCode() : 999,
                'data' => $logData,
                'request_id' => $requestId,
                'msg' => '内部服务异常或参数异常，请先检查参数是否正确，如有疑问，可联系：87989431、87498106咨询。[注]需提供此次接口返回的 request_id 值'
            ], 272);
        }
        unset($throwable);
        return $response->withStatus($code)->withBody(new SwooleStream($data))->withHeader('Content-Type', 'application/json; charset=utf-8');
    }

    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}
